import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository, LessThan, MoreThan } from "typeorm";
import { ChatMessageEntity } from "../entities/chat-message.entity";
import { SystemMessageEntity } from "../entities/system-message.entity";

@Injectable()
export class ChatMessageService {
  constructor(
    @InjectRepository(ChatMessageEntity)
    private chatMessageRepository: Repository<ChatMessageEntity>,
    @InjectRepository(SystemMessageEntity)
    private systemMessageRepository: Repository<SystemMessageEntity>
  ) {}

  /**
   * 获取登录后的消息列表 (act_id: 66)
   * 包含大区、帮派、商业3类消息，总共45条最新消息
   */
  async getLoginMessages(limit: number = 45) {
    try {
      // 计算24小时前的时间
      const twentyFourHoursAgo = new Date();
      twentyFourHoursAgo.setHours(twentyFourHoursAgo.getHours() - 24);

      // 直接查询所有类型的消息，按时间降序获取最新的45条，然后升序排列
      const messages = await this.chatMessageRepository
        .createQueryBuilder("message")
        .select([
          "message.content as c",
          "message.timeDisplay as h",
          "message.id as id",
          "message.senderName as n",
          "message.senderCharacterId as rid",
          "message.messageType as t",
          "message.created_at as created_at",
        ])
        .where("message.isActive = :isActive", { isActive: 1 })
        .andWhere("message.messageType IN (:...messageTypes)", {
          messageTypes: [1, 4, 5], // 大区、帮派、商业消息
        })
        .andWhere("message.created_at >= :twentyFourHoursAgo", {
          twentyFourHoursAgo,
        })
        .orderBy("message.created_at", "DESC")
        .limit(limit)
        .getRawMany();

      // 按时间升序排列（客户端期望的顺序）
      const sortedMessages = messages.sort(
        (a, b) =>
          new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
      );

      // 直接返回SQL查询结果，无需map转换
      return sortedMessages;
    } catch (error) {
      console.error("获取登录消息失败:", error);
      return [];
    }
  }

  /**
   * 根据消息类型获取最新的消息
   * @param messageType 消息类型
   * @param limit 限制条数
   */
  private async getMessagesByType(messageType: number, limit: number) {
    return await this.chatMessageRepository
      .createQueryBuilder("message")
      .select([
        "message.content as c",
        "message.timeDisplay as h",
        "message.id as id",
        "message.senderName as n",
        "message.senderCharacterId as rid",
        "message.messageType as t",
        "message.created_at as created_at",
      ])
      .where("message.isActive = :isActive", { isActive: 1 })
      .andWhere("message.messageType = :messageType", { messageType })
      .orderBy("message.created_at", "DESC")
      .limit(limit)
      .getRawMany();
  }

  /**
   * 发送消息 (c: 260)
   * 支持的消息类型：
   * 1 - 区频道消息 (需要areaId)
   * 4 - 帮派频道消息 (需要factionId)
   * 5 - 商屏消息 (不需要额外参数)
   */
  async sendMessage(messageData: {
    content: string;
    senderName: string;
    senderCharacterId: number;
    messageType: number;
    areaId?: number;
    factionId?: number;
  }) {
    try {
      // 验证消息类型和必要参数
      if (messageData.messageType === 1 && !messageData.areaId) {
        throw new Error("区频道消息必须指定区域ID");
      }
      if (messageData.messageType === 4 && !messageData.factionId) {
        throw new Error("帮派频道消息必须指定帮派ID");
      }
      if (messageData.messageType === 5) {
        // 商屏消息不需要额外参数，清除可能传入的areaId和factionId
        messageData.areaId = undefined;
        messageData.factionId = undefined;
      }

      // 验证消息内容
      if (!messageData.content || messageData.content.trim().length === 0) {
        throw new Error("消息内容不能为空");
      }

      // 生成时间显示格式
      const now = new Date();
      const timeDisplay = `${now.getHours().toString().padStart(2, "0")}:${now
        .getMinutes()
        .toString()
        .padStart(2, "0")}`;

      // 创建消息
      const message = this.chatMessageRepository.create({
        content: messageData.content.trim(),
        timeDisplay: timeDisplay,
        senderName: messageData.senderName,
        senderCharacterId: messageData.senderCharacterId,
        messageType: messageData.messageType,
        areaId: messageData.areaId,
        factionId: messageData.factionId,
        isActive: 1,
        priority: 0,
      });

      const savedMessage = await this.chatMessageRepository.save(message);

      // 记录发送成功的消息
      console.log(
        `✅ 消息发送成功: [${messageData.messageType}] ${messageData.senderName}: ${messageData.content}`
      );

      // 返回发送成功的消息
      return {
        c: savedMessage.content,
        h: savedMessage.timeDisplay,
        id: savedMessage.id,
        n: savedMessage.senderName,
        rid: savedMessage.senderCharacterId,
        t: savedMessage.messageType,
      };
    } catch (error: any) {
      console.error("发送消息失败:", error);
      throw new Error(`发送消息失败: ${error.message}`);
    }
  }

  /**
   * 获取区域消息 (t: 1)
   */
  async getAreaMessages(areaId: number, limit: number = 20) {
    try {
      const messages = await this.chatMessageRepository
        .createQueryBuilder("message")
        .where("message.messageType = :messageType", { messageType: 1 })
        .andWhere("message.areaId = :areaId", { areaId })
        .andWhere("message.isActive = :isActive", { isActive: 1 })
        .orderBy("message.created_at", "DESC")
        .limit(limit)
        .getMany();

      return messages.map((msg) => ({
        c: msg.content,
        h: msg.timeDisplay,
        id: msg.id,
        n: msg.senderName,
        rid: msg.senderCharacterId,
        t: msg.messageType,
      }));
    } catch (error) {
      console.error("获取区域消息失败:", error);
      return [];
    }
  }

  /**
   * 获取商业消息 (t: 5)
   */
  async getBusinessMessages(limit: number = 20) {
    try {
      const messages = await this.chatMessageRepository
        .createQueryBuilder("message")
        .where("message.messageType = :messageType", { messageType: 5 })
        .andWhere("message.isActive = :isActive", { isActive: 1 })
        .orderBy("message.created_at", "DESC")
        .limit(limit)
        .getMany();

      return messages.map((msg) => ({
        c: msg.content,
        h: msg.timeDisplay,
        id: msg.id,
        n: msg.senderName,
        rid: msg.senderCharacterId,
        t: msg.messageType,
      }));
    } catch (error) {
      console.error("获取商业消息失败:", error);
      return [];
    }
  }

  /**
   * 获取帮派消息 (t: 4)
   */
  async getFactionMessages(factionId: number, limit: number = 20) {
    try {
      const messages = await this.chatMessageRepository
        .createQueryBuilder("message")
        .where("message.messageType = :messageType", { messageType: 4 })
        .andWhere("message.factionId = :factionId", { factionId })
        .andWhere("message.isActive = :isActive", { isActive: 1 })
        .orderBy("message.created_at", "DESC")
        .limit(limit)
        .getMany();

      return messages.map((msg) => ({
        c: msg.content,
        h: msg.timeDisplay,
        id: msg.id,
        n: msg.senderName,
        rid: msg.senderCharacterId,
        t: msg.messageType,
      }));
    } catch (error) {
      console.error("获取帮派消息失败:", error);
      return [];
    }
  }

  /**
   * 获取系统消息（从 system_messages 表查询广播消息）
   */
  async getSystemMessages(limit: number = 20) {
    try {
      // 从 system_messages 表查询广播消息
      const systemMessages = await this.systemMessageRepository
        .createQueryBuilder("message")
        .where("message.messageType = :messageType", { messageType: 2 }) // 2 = BROADCAST
        .orderBy("message.created_at", "DESC")
        .limit(limit)
        .getMany();

      return systemMessages.map((msg) => {
        // 从 messageBody 中提取广播消息格式的数据
        let messageBody: any = null;
        try {
          messageBody = msg.messageBody ? JSON.parse(msg.messageBody) : null;
        } catch (error) {
          // 如果解析失败，messageBody 保持为 null
        }

        if (messageBody && messageBody.data) {
          return {
            c: messageBody.data.c || "",
            h: messageBody.data.h || "",
            id: messageBody.data.id || msg.id,
            n: messageBody.data.n || msg.senderName,
            rid: messageBody.data.rid || msg.senderId,
            t: messageBody.data.t || 6,
          };
        }
        // 如果 messageBody 格式不正确，返回默认格式
        return {
          c: "系统消息",
          h: new Date().toLocaleTimeString("zh-CN", {
            hour: "2-digit",
            minute: "2-digit",
          }),
          id: msg.id,
          n: msg.senderName,
          rid: msg.senderId,
          t: 6,
        };
      });
    } catch (error) {
      console.error("获取系统消息失败:", error);
      return [];
    }
  }

  /**
   * 删除消息
   */
  async deleteMessage(messageId: number, senderCharacterId: number) {
    try {
      const message = await this.chatMessageRepository.findOne({
        where: { id: messageId, senderCharacterId },
      });

      if (!message) {
        throw new Error("消息不存在或无权限删除");
      }

      await this.chatMessageRepository.update(messageId, { isActive: 0 });
      return { success: true, message: "消息删除成功" };
    } catch (error) {
      console.error("删除消息失败:", error);
      throw error;
    }
  }

  /**
   * 清理过期消息 (保留最近7天的消息)
   */
  async cleanupOldMessages() {
    try {
      const sevenDaysAgo = new Date();
      sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

      const result = await this.chatMessageRepository
        .createQueryBuilder()
        .update(ChatMessageEntity)
        .set({ isActive: 0 })
        .where("created_at < :date", { date: sevenDaysAgo })
        .andWhere("isActive = :isActive", { isActive: 1 })
        .execute();

      console.log(`清理了 ${result.affected} 条过期消息`);
      return result.affected;
    } catch (error) {
      console.error("清理过期消息失败:", error);
      return 0;
    }
  }

  /**
   * 创建默认的系统消息
   */
  async createDefaultSystemMessages() {
    try {
      const defaultMessages = [
        {
          content: "欢迎来到前缘三国！",
          senderName: "系统",
          senderCharacterId: 1000,
          messageType: 6,
          priority: 1,
        },
        {
          content: "新手大礼包已发放，请查收！",
          senderName: "系统",
          senderCharacterId: 1000,
          messageType: 6,
          priority: 1,
        },
        {
          content: "每日签到可获得丰厚奖励！",
          senderName: "系统",
          senderCharacterId: 1000,
          messageType: 6,
          priority: 0,
        },
      ];

      for (const msgData of defaultMessages) {
        const now = new Date();
        const timeDisplay = `${now.getHours().toString().padStart(2, "0")}:${now
          .getMinutes()
          .toString()
          .padStart(2, "0")}`;

        const message = this.chatMessageRepository.create({
          ...msgData,
          timeDisplay,
          isActive: 1,
        });

        await this.chatMessageRepository.save(message);
      }

      console.log("默认系统消息创建成功");
      return true;
    } catch (error) {
      console.error("创建默认系统消息失败:", error);
      return false;
    }
  }
}
